package com.ics.cmsadmin.modules.auth.service.impl;

import com.ics.cmsadmin.frame.constant.Constants;
import com.ics.cmsadmin.frame.core.annotation.CacheDbMember;
import com.ics.cmsadmin.frame.core.annotation.ClearDbMember;
import com.ics.cmsadmin.frame.core.bean.PageBean;
import com.ics.cmsadmin.frame.core.bean.PageResult;
import com.ics.cmsadmin.frame.core.enums.ApiResultEnum;
import com.ics.cmsadmin.frame.core.enums.CacheGroupEnum;
import com.ics.cmsadmin.frame.core.exception.CmsException;
import com.ics.cmsadmin.frame.core.service.TreeDataService;
import com.ics.cmsadmin.modules.auth.bean.SysUser;
import com.ics.cmsadmin.modules.auth.service.UserService;
import com.ics.cmsadmin.modules.sso.utils.SsoUtils;
import com.ics.cmsadmin.modules.system.emums.RegisterKeyValueEnum;
import com.ics.cmsadmin.modules.system.emums.SequenceNumberEnum;
import com.ics.cmsadmin.modules.wechat.utils.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

import static com.ics.cmsadmin.modules.auth.steward.AuthRepositories.userDao;
import static com.ics.cmsadmin.modules.auth.steward.AuthServices.*;
import static com.ics.cmsadmin.modules.system.steward.SystemServices.registerService;
import static com.ics.cmsadmin.modules.system.steward.SystemServices.sequenceNumberService;


/**
 * Created by lvsw on 2018-03-29.
 */
@Service
public class UserServiceImpl implements UserService {

    @CacheDbMember(returnClass = SysUser.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public SysUser queryById(String id) {
        if (StringUtils.isBlank(id)){
            return null;
        }
        return userDao.queryById(id);
    }

    @CacheDbMember(returnClass = SysUser.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public PageResult<SysUser> list(SysUser bean, PageBean page) {
        long count = userDao.count(bean);
        if (count == 0){
            return new PageResult<>();
        }
        page = page == null ? new PageBean() : page;
        return PageResult.getPage(count, userDao.list(bean, page));
    }

    @CacheDbMember(returnClass = SysUser.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public PageResult<SysUser> listByLoginUserId(SysUser bean, String loginUserId, PageBean page) {
        return listByLoginUserId(bean, loginUserId, page, userDao);
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean insert(SysUser bean) {
        if (bean == null){
            return false;
        }
        if (StringUtils.isBlank(bean.getLoginName())) {
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "登陆名为空");
        }
        if (StringUtils.isBlank(bean.getMobilephone())) {
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "手机号为空");
        }
        if (StringUtils.isBlank(bean.getEmail())) {
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "邮箱为空");
        }
        if (userDao.findOne(SysUser.builder().loginName(bean.getLoginName()).build()) != null){
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "登陆名已经存在");
        }
        if (userDao.findOne(SysUser.builder().mobilephone(bean.getMobilephone()).build()) != null){
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "手机号已经存在");
        }
        if (userDao.findOne(SysUser.builder().email(bean.getEmail()).build()) != null){
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "邮箱已经存在");
        }

        validOrgId(bean);
        String userId = sequenceNumberService.newSequenceNumber(SequenceNumberEnum.USER);
        bean.setUserId(userId);
        addUserDefaultRole(bean);
        return userDao.insert(bean) == 1;
    }

    private void validOrgId(SysUser bean) {
        if (StringUtils.isNotBlank(bean.getOrgId())){
            if (!StringUtils.equalsIgnoreCase(bean.getOrgId(), "agent") &&
                organizationService.queryById(bean.getOrgId()) == null) {
                throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "该组织不存在");
            }
            if (StringUtils.equals(bean.getOrgId(), TreeDataService.DEFAULT_ROOT_ID)){
                bean.setPostType(Constants.USER_POST_TYPE_BOSS);
            }else{
                if (StringUtils.isBlank(bean.getPostType()) || StringUtils.equals(bean.getPostType(), Constants.USER_POST_TYPE_BOSS)) {
                    bean.setPostType(Constants.USER_POST_TYPE_EMPLOYEE);
                }
            }
        }
    }

    /**
     * 新增用户默认角色
     * @param bean
     */
    private void addUserDefaultRole(SysUser bean) {
        String roleId;
        if (StringUtils.equals(bean.getUserType(), Constants.USER_TYPE_AGENT)){
            roleId = registerService.queryRegisterValue(RegisterKeyValueEnum.AGENT_DEFAULT_ROLE_ID, Function.identity());
        }else{
            roleId = registerService.queryRegisterValue(RegisterKeyValueEnum.USER_DEFAULT_ROLE_ID, Function.identity());
        }
        if (roleService.queryById(roleId) == null){
            return;
        }
        userRoleService.addRoles2User(Arrays.asList(roleId), bean.getUserId());
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean update(String id, SysUser bean) {
        SysUser sysUser = queryById(id);
        if (StringUtils.isBlank(id) || bean == null || sysUser == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "参数为空,或用户没找到");
        }
        if (StringUtils.isNotBlank(bean.getLoginName())){
            SysUser loginNameUser = userDao.findOne(SysUser.builder().loginName(bean.getLoginName()).build());
            if (loginNameUser != null && !StringUtils.equals(loginNameUser.getUserId(), id)){
                throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "登陆名已经存在");
            }
        }

        if (StringUtils.isNotBlank(bean.getMobilephone())){
            SysUser mobilephoneUser = userDao.findOne(SysUser.builder().mobilephone(bean.getMobilephone()).build());
            if (mobilephoneUser != null && !StringUtils.equals(mobilephoneUser.getUserId(), id)){
                throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "手机号已经存在");
            }
        }

        if (StringUtils.isNotBlank(bean.getEmail())){
            SysUser emailUser = userDao.findOne(SysUser.builder().email(bean.getEmail()).build());
            if (emailUser != null && !StringUtils.equals(emailUser.getUserId(), id)){
                throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "邮箱已经存在");
            }
        }
        validOrgId(bean);
        return userDao.update(id, bean) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean delete(String id) {
        if (StringUtils.isBlank(id) || queryById(id) == null){
            throw new CmsException(ApiResultEnum.DELETE_TABLE_ITEM_FAIL);
        }
        boolean result = userDao.delete(id) == 1;
        if (result) {
            SsoUtils.deleteLoginInfoFromRedis(id);
        }
        return result;
    }

    @CacheDbMember(returnClass = SysUser.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public SysUser findUserByUserNameAndPassword(String userName, String password) {
        if (StringUtils.isBlank(userName) || StringUtils.isBlank(password)){
            return null;
        }
        return userDao.findOne(SysUser.builder().status(Constants.ENABLE_STATUS).loginName(userName).password(password).build());
    }

    @CacheDbMember(returnClass = SysUser.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public SysUser findUserByMobilephoneAndPassword(String mobilephone, String password) {
        if (StringUtils.isBlank(mobilephone) || StringUtils.isBlank(password)){
            return null;
        }
        return userDao.findOne(SysUser.builder().status(Constants.ENABLE_STATUS).mobilephone(mobilephone).password(password).build());
    }

    @CacheDbMember(returnClass = SysUser.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public SysUser findUserByEmailAndPassword(String email, String password) {
        if (StringUtils.isBlank(email) || StringUtils.isBlank(password)){
            return null;
        }
        return userDao.findOne(SysUser.builder().status(Constants.ENABLE_STATUS).email(email).password(password).build());
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean recovery(String userId) {
        return userDao.recovery(userId) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean resetPassword(String userId) {
        return resetPassword(userId, null);
    }

    @Override
    public boolean resetPassword(String userId, String newPassword) {
        if (StringUtils.isBlank(userId)){
            return false;
        }
        if (StringUtils.isBlank(newPassword)){
            newPassword = MD5Util.MD5Encode("123456", "utf8");
        }
        boolean result = userDao.resetPassword(userId, newPassword) == 1;
        if (result) {
            SsoUtils.deleteLoginInfoFromRedis(userId);
        }
        return result;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean modifyPassword(String userId, String oldPasswrod, String newPassword) {
        SysUser sysUser = queryById(userId);
        if (sysUser == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "没找到用户");
        }
        SysUser tempSysUser = findUserByUserNameAndPassword(sysUser.getLoginName(), oldPasswrod);
        if (tempSysUser == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "旧密码输入有误");
        }
        boolean result = userDao.modifyPassword(userId, newPassword) == 1;
        if (result){
            SsoUtils.deleteLoginInfoFromRedis(userId);
        }
        return result;
    }

    @CacheDbMember(returnClass = SysUser.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public SysUser findOne(SysUser sysUser) {
        return userDao.findOne(sysUser);
    }

    @Override
    public boolean asEmployee(String userId) {
        if (queryById(userId) == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "没找到该用户");
        }
        update(userId, SysUser.builder().postType(Constants.USER_POST_TYPE_EMPLOYEE).build());
        updateUserPostRole(userId, null);
        return true;
    }

    @Override
    public boolean asAssistant(String userId) {
        if (queryById(userId) == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "没找到该用户");
        }
        update(userId, SysUser.builder().postType(Constants.USER_POST_TYPE_ASSISTANT).build());
        updateUserPostRole(userId, RegisterKeyValueEnum.ASSISTANT_DEFAULT_ROLE_ID);
        return true;
    }

    @Override
    public boolean asManager(String userId) {
        if (queryById(userId) == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "没找到该用户");
        }
        update(userId, SysUser.builder().postType(Constants.USER_POST_TYPE_MANAGER).build());
        updateUserPostRole(userId, RegisterKeyValueEnum.MANAGER_DEFAULT_ROLE_ID);
        return true;
    }

    @Override
    public boolean asBoss(String userId) {
        if (queryById(userId) == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "没找到该用户");
        }
        update(userId, SysUser.builder().postType(Constants.USER_POST_TYPE_BOSS).orgId(TreeDataService.DEFAULT_ROOT_ID).build());
        updateUserPostRole(userId, RegisterKeyValueEnum.BOSS_DEFAULT_ROLE_ID);
        return true;
    }

    private void updateUserPostRole(String userId, RegisterKeyValueEnum wantAddRoleRegisterKey) {
        String bossRole = registerService.queryRegisterValue(RegisterKeyValueEnum.BOSS_DEFAULT_ROLE_ID, Function.identity());
        String managerRole = registerService.queryRegisterValue(RegisterKeyValueEnum.MANAGER_DEFAULT_ROLE_ID, Function.identity());
        String assistantRole = registerService.queryRegisterValue(RegisterKeyValueEnum.ASSISTANT_DEFAULT_ROLE_ID, Function.identity());
        List<String> wantDeleteRole = Arrays.asList(bossRole, managerRole, assistantRole);
        userRoleService.removeRoles2User(wantDeleteRole, userId);
        if (wantAddRoleRegisterKey != null){
            String wantAddRole = registerService.queryRegisterValue(wantAddRoleRegisterKey, Function.identity());
            if (roleService.queryById(wantAddRole) != null){
                userRoleService.addRoles2User(Arrays.asList(wantAddRole), userId);
            }
        }
    }
}
